﻿using K8.EF;
using Microsoft.EntityFrameworkCore.Metadata.Conventions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection.Metadata;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace KingerRobot.PCRBW.SpiService;

public class RcsLocationRepositories: IRcsLocationRepositories
{
    #region 同步方法
    public PORcsLocation QueryById(long objId)
    {
        var _db = Db.Default;
        return _db.RcsLocations.FirstOrDefault(d => d.Id == objId);
    }

    /// <summary>
    /// 功能描述:根据ID查询数据
    /// 作　　者:Robin
    /// </summary>
    /// <param name="lstIds">id列表,如果是联合主键，请使用Where条件</param>
    /// <returns>数据实体列表</returns>
    public List<PORcsLocation> QueryByIDs(object[] lstIds)
    {
        var _db = Db.Default;
        return _db.RcsLocations.Where(d => lstIds.Contains(lstIds)).ToList();
    }

    /// <summary>
    /// 写入实体数据
    /// </summary>
    /// <param name="entity">博文实体类</param>
    /// <returns>插入个数 插入成功为1</returns>
    public int Add(PORcsLocation entity)
    {
        var _db = Db.Default;
        return _db.RcsLocations.Insert(entity);
    }

    /// <summary>
    /// 批量插入实体
    /// </summary>
    /// <param name="listEntity">实体集合</param>
    /// <returns>影响行数</returns>
    public int Add(IEnumerable<PORcsLocation> listEntity)
    {
        var _db = Db.Default;
        _db.RcsLocations.AddRange(listEntity);
        int insertedCount = _db.SaveChanges();
        return insertedCount;
    }
    /// <summary>
    /// 根据实体删除一条数据
    /// </summary>
    /// <param name="entity">博文实体类</param>
    /// <returns></returns>
    public int DeleteById(long id)
    {
        var _db = Db.Default;
        return _db.RcsLocations.Where(d => d.Id == id).Delete();
    }

    /// <summary>
    /// 删除指定ID集合的数据(批量删除)
    /// </summary>
    /// <param name="ids">主键ID集合</param>
    /// <returns></returns>
    public int Deletes(IEnumerable<PORcsLocation> entitys)
    {
        try
        {
            var _db = Db.Default;
            _db.RcsLocations.BulkDelete(entitys);
            int result = _db.SaveChanges();
            return result;
        }
        catch (Exception ex)
        {
            return 0;
        }
    }
    /// <summary>
    /// 更新实体数据
    /// </summary>
    /// <param name="entity">博文实体类</param>
    /// <returns></returns>
    public int Update(PORcsLocation entity)
    {
        var _db = Db.Default;
        return _db.RcsLocations.Update<PORcsLocation>(entity);
    }
    /// <summary>
    /// 待条件更新所有数据
    /// </summary>
    /// <param name="whereExpression"></param>
    /// <param name="entity"></param>
    /// <returns></returns>
    public int Update(Expression<Func<PORcsLocation, bool>> whereExpression, PORcsLocation entity)
    {
        var _db = Db.Default;
        return _db.RcsLocations.Where(whereExpression).Update(entity);
    }

    /// <summary>
    /// 正序查询第一条数据
    /// </summary>
    /// <returns></returns>
    public PORcsLocation First()
    {
        var _db = Db.Default;
        return _db.RcsLocations.First();
    }
    /// <summary>
    /// 查询第一条数据
    /// </summary>
    /// <param name="whereExpression"></param>
    /// <returns></returns>
    public PORcsLocation First(Expression<Func<PORcsLocation, bool>> whereExpression)
    {
        var _db = Db.Default;
        if (whereExpression == null) return null;
        var rscLoction = _db.RcsLocations.Where(whereExpression).ToList();
        if (rscLoction==null || rscLoction.Count()==0)
        {
            return null;
        }
        return rscLoction.OrderBy(d=>d.MdTime).First();
    }


    /// <summary>
    /// 功能描述:查询所有数据
    /// 作　　者:Robin
    /// </summary>
    /// <returns>数据列表</returns>
    public List<PORcsLocation> Query()
    {
        try
        {
            var _db = Db.Default;
            return _db.RcsLocations.ToList();
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Query执行异常:{ex.Message}");
        }
        return null;
    }


    /// <summary>
    /// 功能描述:查询数据列表
    /// 作　　者:Robin
    /// </summary>
    /// <param name="whereExpression">whereExpression</param>
    /// <returns>数据列表</returns>
    public List<PORcsLocation> Query(Expression<Func<PORcsLocation, bool>> whereExpression)
    {
        var _db = Db.Default;
        if (whereExpression == null) return null;
        return _db.RcsLocations.Where(whereExpression).ToList();
    }


    /// <summary>
    /// 根据sql语句查询
    /// </summary>
    /// <param name="strSql">完整的sql语句</param>
    /// <param name="parameters">参数</param>
    /// <returns>泛型集合</returns>
    public List<PORcsLocation> QuerySql(string strSql, Parameter[] parameters = null)
    {
        var _db = Db.Default;
        var result = _db.RcsLocations.FromSqlRaw(strSql, parameters).ToList();

        return result;
    }
    /// <summary>
    /// 根据sql语句查询 执行update、delete、add
    /// </summary>
    /// <param name="strSql">完整的sql语句</param>
    /// <returns>泛型集合</returns>
    public int ExecuteSqlRaw(string strSql, Parameter[] parameters)
    {
        var dbHelper = new DbHelper();
        dbHelper.CommandText = strSql.ToString();
        dbHelper.CommandType = System.Data.CommandType.Text;
        for (int i = 0; i < parameters.Length; i++)
        {
            dbHelper.AddParameter(parameters[i]);
        }
        int rowsReturned = dbHelper.ExecuteNonQuery();

        return rowsReturned;
    }

    #endregion


    #region 根据滑台位置查询放货位
    /// <summary>
    /// 根据滑台位置查询最近放货位
    /// </summary>
    /// <param name="locId">开始货位</param>
    /// <returns></returns>
    public POWcsEquipLocHold GetDistancePoint(MesProduct mesProduct, PORcsLocation rcsLoction)
    {
        POWcsEquipLocHold result = null;
        List<PORcsLocation> locations = null;
        var db = Db.Default;
        #region 计算距离进库滑台最近货位
        if (mesProduct.PassFlag == "2")//不合格产品
        {
            locations = db.RcsLocations.Where(r => r.LocType == (int)EnumLocationType.Goods && r.LocHasSku == 0 && r.TaskOccupy == 0 
            && r.LocEnable == 1 && r.InEnable == 1&& r.UseFlag == 1).ToList();
        }
        else
        {
            locations = db.RcsLocations.Where(r => r.LocType == 3 && r.LocHasSku == 0 && r.TaskOccupy == 0 && r.UseFlag == 1 && r.LocEnable == 1
                                  && r.InEnable == 1 ).ToList();
        }
        if (locations is null || locations.Count == 0)
        {
            WriteLog($"入库库位查询》未查询到库位信息，订单类型：{mesProduct.PassFlag}", true);
            return result;
        }
        RscDto rscDto = new RscDto() { AxisX = rcsLoction.AxisX, AxisY = rcsLoction.AxisY };
        PORcsLocation location = GetDistancePoint(locations, rscDto);
        if (location == null)
        {
            WriteLog("没有找到距离最近的货位");
            return result;
        }

        #endregion
        result = db.WcsEquipLocHolds.FirstOrDefault(d => d.LocId == location.Id);
        return result;
    }
    public static PORcsLocation GetDistancePoint(List<PORcsLocation> points, RscDto target)
    {
        return points.OrderBy(p => Distance(p, target)).FirstOrDefault();
    }
    public static double Distance(PORcsLocation p1, RscDto p2)
    {
        return Math.Sqrt(Math.Pow(Convert.ToDouble(p2.AxisX - p1.AxisX), 2) + Math.Pow(Convert.ToDouble(p2.AxisY - p1.AxisY), 2));
    }


    #endregion


    #region 查询可用的开始货位——出库
    /// <summary>
    /// 查询可用的开始货位
    /// </summary>
    /// <param name="p1"></param>
    /// <param name="p2"></param>
    /// <returns></returns>
    public (PORcsLocation, int) QueryStartLocation(Expression<Func<PORcsLocation, bool>> whereExpression)
    {
        PORcsLocation rcsLocation = null;

        var db = Db.Default;
        var list = (from r in db.RcsLocations
                    join c in db.MesChecks on r.MaterialId equals c.part_number
                    where r.ProductBatch == c.batch_name && r.OutLock ==1
                    select r).OrderBy(d => d.MdTime);

        if (list == null || list.Count() == 0)
        {
            return (rcsLocation, -1);
        }
        var result = (list.Where(whereExpression).OrderBy(d => d.MdTime)).FirstOrDefault();
        if (result == null)
        {
            return (rcsLocation, -2);
        }
        return (rcsLocation, 1);

    }
    #endregion

    #region 查询可用的开始货位——人工出库
    /// <summary>
    /// 查询可用的开始货位
    /// </summary>
    /// <param name="p1"></param>
    /// <param name="p2"></param>
    /// <returns></returns>
    public PORcsLocation QueryLocation(Expression<Func<PORcsLocation, bool>> whereExpression)
    {
        PORcsLocation rcsLocation = null;

        var db = Db.Default;
        var result = (db.RcsLocations.Where(whereExpression).OrderBy(d => d.MdTime)).FirstOrDefault();
        return result;
    }
    #endregion
}
